AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )

util.PrecacheSound( "Crane_magnet_toggle" )
util.PrecacheSound( "apc_engine_stop" )
util.PrecacheSound( "crane_extend_stop" )
util.PrecacheSound( "coast.crane_magnet_hum" )
util.PrecacheSound( "d1_canals.Floodgate_Klaxon" )
util.PrecacheSound( "DoorHandles.Unlocked1")
include('shared.lua')

local Energy_Increment = 50
local SellAmount = { easy = 1000 , medium = 250 , hard = 100 , tough = 10 }

function ENT:Initialize()
    self.BaseClass.Initialize(self)

    local phys = self.Entity:GetPhysicsObject()
	if (phys:IsValid()) then
		phys:Wake()
		phys:SetMass(300)
	end
	
	self.damaged = 0
    self:SetMaxHealth(600)
	self:SetHealth(self:GetMaxHealth())

	self.Active = 0
	self.tink = 0
	self.tink2 = 0
	self.thinkcount = 0
	self.Multiplier = 1
	self:SetMoney(0)
	self.mprint = 0
	self.cashoutreserve = 0
	
	self.cashout = false
	self.debugger = false

	self.sell_energy = false

	if not (WireAddon == nil) then
		self.WireDebugName = self.PrintName
		self.Inputs = WireLib.CreateInputs(self.Entity, { "On" , "Sell Energy" , "Cashout" })
		self.Outputs = WireLib.CreateSpecialOutputs(self.Entity, { "On", "EnergyUsage", "Money" , "Prices-Names" , "Prices-Values" }, { "NORMAL", "NORMAL", "NORMAL", "ARRAY", "ARRAY" })
	else
		self.Inputs = {Name="On"}
	end
	MoneyCFG.HasSeller = true
end

function ENT:AddMoney(value)
	if (value > 0) then
		self:SetMoney(self:GetMoney() + value)
	end
end

function ENT:RemoveMoney(value)
	if (value > 0) then
		self:SetMoney(self:GetMoney() - value)
	end
end
function ENT:SetMoney(value)
	self:SetNWInt("moneystorage",value)
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Money", math.Round(value)) end
end
function ENT:GetMoney()
	return self:GetNWInt("moneystorage")
end
function ENT:PrintMoney(howmuch)
	local fwd = self:GetForward()
	local pos = self:GetPos()
	entm = ents.Create('ams_money')
	--if !ent:IsValid() then return false end
	entm.value = howmuch
	entm:Spawn() --run ENT:Initialize()
	local height = entm:OBBMaxs().z - entm:OBBMins().z		
	local SpawnPos = ( pos + Vector(0,0,325 + (5+height)) ) + (fwd*100)
	entm:SetPos(SpawnPos)
	entm:SetAngles(Angle(math.Rand(-2,2), math.Rand(-180,180), math.Rand(-2,2)))
	entm:Activate()
	local physm = entm:GetPhysicsObject()
	if physm:IsValid() then
		physm:SetMaterial( "gmod_silent" )
		physm:AddVelocity( (fwd*(75+math.Rand(-5,5)))+ Vector(0, 0, 300+math.Rand(-15,15)) )
	end
	self:EmitSound("DoorHandles.Unlocked1")
end
function ENT:ExpellMoney()
	if (self.cashout) then
		self.cashout = false
		self.cashoutreserve = math.floor(self:GetMoney() / 100) * 100
		self:RemoveMoney(self.cashoutreserve)
	end
	if (self.cashoutreserve > 0) then
		local s_100000 = math.floor(self.cashoutreserve / 100000)
		local s_50000 = math.floor(self.cashoutreserve / 50000)
		local s_10000 = math.floor(self.cashoutreserve / 10000)
		local s_1000 = math.floor(self.cashoutreserve / 1000)
		local s_100 = math.floor(self.cashoutreserve / 100)
		if (self.mprint > 0) then self.mprint = self.mprint - 1 return end
		if (s_100000 > 0) then self.mprint = 1 self:PrintMoney(100000) self.cashoutreserve = self.cashoutreserve - 100000 return end
		if (s_50000 > 0) then self:PrintMoney(50000) self.cashoutreserve = self.cashoutreserve - 50000 return end
		if (s_10000 > 0) then self:PrintMoney(10000) self.cashoutreserve = self.cashoutreserve - 10000 return end
		if (s_1000 > 0) then self:PrintMoney(1000) self.cashoutreserve = self.cashoutreserve - 1000 return end
		if (s_100 > 0) then self:PrintMoney(100) self.cashoutreserve = self.cashoutreserve - 100 return end
	end
end

function ENT:TurnOn()
	if (self.Active == 0) then
		self.Entity:EmitSound( "coast.crane_magnet_hum" )
		self.Entity:EmitSound( "Crane_magnet_toggle" )
		self.Active = 1
		self:SetOOO(1)
		if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "On", self.Active) end
	end
end

function ENT:TurnOff()
	if (self.Active == 1) then
		self:StopSound("coast.crane_magnet_hum")
		self:StopSound("d1_canals.Floodgate_Klaxon")
		self.Entity:EmitSound( "crane_extend_stop" )
		self.Entity:EmitSound( "apc_shutdown" )
		self.Active = 0
		self:SetOOO(0)
		if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "On", self.Active) end
		if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "EnergyUsage", 0) end
	end
end

function ENT:SetActive( value )
	if (value) then
		if (value != 0 and self.Active == 0 ) then
			self:TurnOn()
		elseif (value == 0 and self.Active == 1 ) then
			self:TurnOff()
		end
	end
end

function ENT:TriggerInput(iname, value)
	if (iname == "On") then
		self:SetActive(value)
	elseif (iname == "Sell Energy") then
		if (value > 0) then self.sell_energy = true else self.sell_energy = false end
	--elseif (iname == "Test") then
	--	if (value > 0) then self.debugger = true else self.debugger = false end
	elseif (iname == "Cashout") then
		if (value > 0) then
			if (self.cashoutreserve > 0) then
				self.cashout = false
			else
				self.cashout = true
			end
		else
			self.cashout = false
		end
	end
end

function ENT:OnRemove()
    self.BaseClass.OnRemove(self)
	MoneyCFG.HasSeller = false
	self:StopSound("coast.crane_magnet_hum")
end

function ENT:Damage()
	if (self.damaged == 0) then
		self.damaged = 1
	end
end
/*
function ENT:TakeDamage(amount, attacker, inflictor)
	self.BaseClass:TakeDamage(self, amount, attacker, inflictor)
	--self:SetHealth(self:Health()-amount)
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "Health", self:Health()) end
	--if self:Health()<=0 then
	--	self:Destruct()
	--end
end
*/
function ENT:Repair()
	self.Entity:SetColor(255,255,255,255)
	self:SetHealth(self:GetMaxHealth())
	self.damaged = 0
end

function ENT:Destruct()
	if CAF and CAF.GetAddon("Life Support") then
		CAF.GetAddon("Life Support").Destruct( self.Entity, false )
	end
end
/*
function ENT:Output()
	return 1
end

function ENT:ShowOutput()
	self.Entity:SetNetworkedInt( 1, self.force or 0 )
	
	--send res values
	local netid = 10
	for k,v in pairs(self.reslist) do
		self.Entity:SetNWInt( netid ,k) -- energy consumption
	end
end
*/

function ENT:Sell_Resources()
	self.energy = self:GetResourceAmount("energy")
	local resamount, en_sold, tot_sold
	local SM = CAF.GetAddon("Selling Machine")
	
	local tosell = 0
	local mul = 1
	local somesold = false
	local einc = Energy_Increment * self.Multiplier
	
	einc = math.ceil(einc * self:GetMultiplier())
	if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "EnergyUsage", math.Round(einc)) end
	if (self.energy >= einc || self.debugger) then
		self:ConsumeResource("energy", einc)
		if (self.sell_energy) then
			if (self.energy - einc > 0) then
				tosell = math.random(80,100)
				en_sold = self:ConsumeResource("energy",  SellAmount[SM.resources.energy.type] * (tosell/100) * self:GetMultiplier())
				self:AddMoney(en_sold * SM.resources.energy.value  * (SM.resources.energy.marked / 100))
				if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "EnergyUsage", math.Round(self.Outputs.EnergyUsage.Value + en_sold)) end
				somesold = true
			end
		end
		tot_sold = 0
		for k, v in pairs(SM.resources) do
			resamount = self:GetResourceAmount(k)
			if (resamount > 0 && k != "energy") then
				if (not SellAmount[v.type]) then ErrorNoHalt("Seller Machine - Error in type!") break end
				tosell = math.random(80,100)
				en_sold = self:ConsumeResource(k, SellAmount[v.type] * (tosell/100) * self:GetMultiplier())
				self:AddMoney(en_sold * v.value * (v.marked / 100))
				tot_sold = tot_sold + en_sold
				somesold = true
			end
		end
		if (tot_sold > 0) then
			local consumed_extra = self:ConsumeResource("energy", tot_sold / 500)
			if not (WireAddon == nil) then Wire_TriggerOutput(self.Entity, "EnergyUsage", math.Round(self.Outputs.EnergyUsage.Value + consumed_extra)) end
		end
		if (not somesold) then
			--self:TurnOff()
			if (self.debugger) then self:AddMoney(math.random(100,100000)) end
			self:EmitSound("d1_canals.Floodgate_Klaxon")
		end
		--self:SupplyResource(self.caf.custom.resource, ainc)
	else
		self:TurnOff()
	end
end

function ENT:Think()
	self.BaseClass.Think(self)
	if (CurTime() >= (self.tink+1)) then
		if ( self.Active == 1 ) then
			self:Sell_Resources()
			self.tink = CurTime()
		end
	end
	if (CurTime() >= (self.tink2+0.33)) then
		self:ExpellMoney()
		self.tink2 = CurTime()
	end
	--self.Entity:NextThink( CurTime() + 0.01 )
	--return true
end

function ENT:AcceptInput(name,activator,caller)
	if name == "Use" and caller:IsPlayer() and caller:KeyDownLast(IN_USE) == false then
		if ( self.Active == 0 ) then
			self:TurnOn()
		else
			self:TurnOff()
		end
	end
end

/*
function ENT:PreEntityCopy()
    self.BaseClass.PreEntityCopy(self)
end

function ENT:PostEntityPaste( Player, Ent, CreatedEntities )
    self.BaseClass.PostEntityPaste(self, Player, Ent, CreatedEntities )
end
*/